package com.lovo.ssc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lovo.csc.dto.ExpenseDto;
import com.lovo.csc.dto.PrepayDto;
import com.lovo.ssc.bean.LevelBean;
import com.lovo.ssc.bean.Rechargerecord;
import com.lovo.ssc.bean.SysUser;
import com.lovo.ssc.interceptor.CartInterceptor;
import com.lovo.ssc.mapper.LevelMapper;
import com.lovo.ssc.service.ILevelService;
import com.lovo.ssc.service.IRechargerecordService;
import com.lovo.ssc.service.ISysUserService;
import com.lovo.ssc.vo.UserVo;
import com.lovo.sscsys.remoteService.IsscsysRemoteService;
import com.lovo.util.MQUtil;
import com.lovo.vo.TopUpVO;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * <p>
 * 用户等级表，不同等级对应不同的折扣率 服务实现类
 * </p>
 *
 * @author lovo
 * @since 2022-07-11
 */
@Service
public class LevelServiceImpl extends ServiceImpl<LevelMapper, LevelBean> implements ILevelService {
    //MQ模板对象
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ILevelService levelService;
    @Autowired
    private IRechargerecordService rechargerecordService;
    @Autowired
    private IsscsysRemoteService isscsysRemoteService;

    //充值金额
    private Float money;
    //充值状态：0充值中，1充值成功
    private int i = 0;

    /**
     * 通过等级名查询折扣
     *
     * @param levelName 等级名
     * @return 折扣率
     */
    @Override
    public float findDiscount(String levelName) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("levelName", levelName);
        LevelBean levelBean = baseMapper.selectOne(qw);
        return levelBean.getDiscount();
    }

    /**
     * 监听审核系统返回的折扣率
     *
     * @param prepayDto 折扣率对象
     */
    @RabbitListener(queues = MQUtil.DepositQueue)
//    Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag,
    public void getDiscount(Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag, PrepayDto prepayDto) throws IOException {
        System.out.println("接收到审核返还折扣"+prepayDto);

        QueryWrapper qw = new QueryWrapper();
        qw.eq("levelName", prepayDto.getUserGrade());
        LevelBean levelBean = levelService.getOne(qw);
        levelBean.setDiscount(prepayDto.getDiscountRate());
        levelService.saveOrUpdate(levelBean);
        System.out.println("修改等级折扣");
        //修改本地数据库用户等级
        QueryWrapper qw2 = new QueryWrapper();
        qw2.eq("userName", prepayDto.getUserCode());
        SysUser sysUser = sysUserService.getOne(qw2);
        sysUser.setUserLevel(prepayDto.getUserGrade());
        sysUserService.saveOrUpdate(sysUser);
        System.out.println("修改本地数据库用户等级");


        //修改后端系统用户等级
//        isscsysRemoteService.updateGrade(sysUser.getUserName(), prepayDto.getUserGrade());
        System.out.println("修改后端系统用户等级");
        this.i = 1;
        System.out.println("改充值状态为"+this.i);
        System.out.println("充值完毕");
        channel.basicAck(tag, false);
    }
    @Override
    public boolean sendMoney(TopUpVO topUpVO) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("userName",topUpVO.getUserCode());
        SysUser sysUser = sysUserService.getOne(qw);
        Integer userId = sysUser.getUserId();
        //设置用户余额
        //将金额四舍五入
        Double oldMoney = topUpVO.getCurrentMoney();
        BigDecimal two = new BigDecimal(oldMoney);
        Double newMoney = two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
        sysUser.setDepositMoney(newMoney);
        sysUserService.saveOrUpdate(sysUser);
        //设置充值记录
        Rechargerecord rechargerecord = new Rechargerecord();
        rechargerecord.setUserid(userId);
        rechargerecord.setOperationNum((float)topUpVO.getMoney());
        rechargerecord.setOperationType("充值");
        LocalDateTime dateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss");
        rechargerecord.setOperationDate(dateTime.format(formatter));
        rechargerecordService.save(rechargerecord);
        
        rabbitTemplate.convertAndSend(MQUtil.moneyDirectExchange, MQUtil.moneyKey, topUpVO);
        System.out.println("投递金额到审核");
        return true;
    }

    /**
     * 监听消费队列
     *
     * @param expenseDto 消费金额对象
     */
    @RabbitListener(queues = MQUtil.ExpenseQueue)
    public void getBuyMoney(Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag, ExpenseDto expenseDto) throws IOException {
        Rechargerecord rechargerecord = new Rechargerecord();
        rechargerecord.setOperationNum(-1 * expenseDto.getMoney());
        rechargerecord.setOperationType("消费");

        QueryWrapper qw = new QueryWrapper();
        qw.eq("userName", expenseDto.getUserName());
        SysUser sysUser = sysUserService.getOne(qw);
        //减余额
        //将金额四舍五入
        Double oldMoney = sysUser.getDepositMoney() - expenseDto.getMoney();
        BigDecimal two = new BigDecimal(oldMoney);
        Double newMoney = two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();

        sysUser.setDepositMoney(newMoney);
        sysUserService.saveOrUpdate(sysUser);

        rechargerecord.setUserid(sysUser.getUserId());

        LocalDateTime dateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss");
        rechargerecord.setOperationDate(dateTime.format(formatter));

        rechargerecordService.save(rechargerecord);
        channel.basicAck(tag, false);
    }

    /**
     * 监听退款队列
     *
     * @param expenseDto 退款对象
     */
    @RabbitListener(queues = MQUtil.ReturnInformQueue)
    public void getRefund(Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag, ExpenseDto expenseDto) throws IOException {
        System.out.println(expenseDto+"退款对象");
        //设置退款记录
        Rechargerecord rechargerecord = new Rechargerecord();
        rechargerecord.setOperationNum(expenseDto.getMoney());
        rechargerecord.setOperationType("退款");

        QueryWrapper qw = new QueryWrapper();
        qw.eq("userName", expenseDto.getUserName());
        SysUser sysUser = sysUserService.getOne(qw);
        System.out.println(sysUser+"要退款的用户");
        //加余额

        Double oldMoney = sysUser.getDepositMoney() + expenseDto.getMoney();
        BigDecimal two = new BigDecimal(oldMoney);
        Double newMoney = two.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
        sysUser.setDepositMoney(newMoney);
        sysUserService.saveOrUpdate(sysUser);

        rechargerecord.setUserid(sysUser.getUserId());

        LocalDateTime dateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss");
        rechargerecord.setOperationDate(dateTime.format(formatter));

        rechargerecordService.save(rechargerecord);
        channel.basicAck(tag, false);
    }

    /**
     * 查询充值状态
     *
     * @return 是否充值成功
     */
    public Boolean findRechargeState() {
        System.out.println("查询充值状态为"+this.i);
        if (this.i == 1) {
            this.i = 0;
            return true;
        }

        return false;
    }

    /**
     * 查询用户余额
     *
     * @return 余额
     */
    @Override
    public Double findMoney() {
        UserVo userVo = CartInterceptor.thread.get();
        SysUser sysUser = sysUserService.getById(userVo.getUserId());
        return sysUser.getDepositMoney();
    }

    /**
     * 查询预存款收支记录
     *
     * @return 收支记录
     */
    @Override
    public List<Rechargerecord> findRechargerecord() {
        UserVo userVo = CartInterceptor.thread.get();
        QueryWrapper qw = new QueryWrapper();
        qw.eq("userId", userVo.getUserId());

        return rechargerecordService.list(qw);
    }
}
